package com.reactim.message.controller;

import com.reactim.message.protection.AnomalyDetectionResult;
import com.reactim.message.protection.ResourceProtectionService;
import com.reactim.message.protection.ResourceUsageStats;
import com.reactim.common.response.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * 资源保护控制器
 * 提供资源保护和限流的监控接口
 */
@RestController
@RequestMapping("/api/resource-protection")
@RequiredArgsConstructor
@Slf4j
public class ResourceProtectionController {

    private final ResourceProtectionService resourceProtectionService;

    /**
     * 获取资源使用统计
     *
     * @return 资源使用统计信息
     */
    @GetMapping("/stats")
    public Result<ResourceUsageStats> getResourceUsageStats() {
        try {
            ResourceUsageStats stats = resourceProtectionService.getResourceUsageStats();
            return Result.success(stats);
            
        } catch (Exception e) {
            log.error("获取资源使用统计失败", e);
            return Result.error("获取资源使用统计失败: " + e.getMessage());
        }
    }

    /**
     * 获取资源使用概览
     *
     * @return 资源使用概览信息
     */
    @GetMapping("/overview")
    public Result<Map<String, Object>> getResourceOverview() {
        try {
            ResourceUsageStats stats = resourceProtectionService.getResourceUsageStats();
            
            Map<String, Object> overview = Map.of(
                "globalConnectionCount", stats.getGlobalConnectionCount(),
                "activeUserCount", stats.getActiveUserCount(),
                "activeIpCount", stats.getActiveIpCount(),
                "maxUserConnections", stats.getMaxUserConnections(),
                "maxIpConnections", stats.getMaxIpConnections(),
                "connectionRejectionRate", stats.getConnectionRejectionRate(),
                "totalConnectionsCreated", stats.getTotalConnectionsCreated(),
                "totalConnectionsRejected", stats.getTotalConnectionsRejected(),
                "totalRequestsRateLimited", stats.getTotalRequestsRateLimited(),
                "activeRateLimiters", stats.getActiveRateLimiters()
            );
            
            return Result.success(overview);
            
        } catch (Exception e) {
            log.error("获取资源使用概览失败", e);
            return Result.error("获取资源使用概览失败: " + e.getMessage());
        }
    }

    /**
     * 检查用户连接是否被允许
     *
     * @param userId 用户ID
     * @param clientIp 客户端IP
     * @return 连接检查结果
     */
    @GetMapping("/check-connection")
    public Mono<Result<Map<String, Object>>> checkConnectionAllowed(
            @RequestParam Long userId,
            @RequestParam(required = false, defaultValue = "127.0.0.1") String clientIp) {
        
        return resourceProtectionService.checkConnectionAllowed(userId, clientIp)
                .map(result -> {
                    Map<String, Object> response = Map.of(
                        "allowed", result.isAllowed(),
                        "reason", result.getReason() != null ? result.getReason() : "连接被允许"
                    );
                    return Result.success(response);
                })
                .onErrorResume(error -> {
                    log.error("检查连接权限失败: userId={}, clientIp={}", userId, clientIp, error);
                    return Mono.just(Result.error("检查连接权限失败: " + error.getMessage()));
                });
    }

    /**
     * 检查请求频率限制
     *
     * @param userId 用户ID
     * @param clientIp 客户端IP
     * @return 频率限制检查结果
     */
    @GetMapping("/check-rate-limit")
    public Mono<Result<Map<String, Object>>> checkRequestRateLimit(
            @RequestParam Long userId,
            @RequestParam(required = false, defaultValue = "127.0.0.1") String clientIp) {
        
        return resourceProtectionService.checkRequestRateLimit(userId, clientIp)
                .map(allowed -> {
                    Map<String, Object> response = Map.of(
                        "allowed", allowed,
                        "message", allowed ? "请求被允许" : "请求频率超限"
                    );
                    return Result.success(response);
                })
                .onErrorResume(error -> {
                    log.error("检查请求频率限制失败: userId={}, clientIp={}", userId, clientIp, error);
                    return Mono.just(Result.error("检查请求频率限制失败: " + error.getMessage()));
                });
    }

    /**
     * 检测异常连接行为
     *
     * @param userId 用户ID
     * @return 异常检测结果
     */
    @GetMapping("/detect-anomaly/{userId}")
    public Mono<Result<AnomalyDetectionResult>> detectAnomalousConnection(@PathVariable Long userId) {
        return resourceProtectionService.detectAnomalousConnection(userId)
                .map(Result::success)
                .onErrorResume(error -> {
                    log.error("检测异常连接行为失败: userId={}", userId, error);
                    return Mono.just(Result.error("检测异常连接行为失败: " + error.getMessage()));
                });
    }

    /**
     * 手动清理过期数据
     *
     * @return 清理结果
     */
    @PostMapping("/cleanup")
    public Result<String> cleanupExpiredData() {
        try {
            log.info("手动触发清理过期数据");
            resourceProtectionService.cleanupExpiredData();
            return Result.success("过期数据清理完成");
            
        } catch (Exception e) {
            log.error("手动清理过期数据失败", e);
            return Result.error("清理过期数据失败: " + e.getMessage());
        }
    }

    /**
     * 模拟连接建立（用于测试）
     *
     * @param userId 用户ID
     * @param clientIp 客户端IP
     * @return 操作结果
     */
    @PostMapping("/simulate-connection")
    public Result<String> simulateConnectionEstablished(
            @RequestParam Long userId,
            @RequestParam(required = false, defaultValue = "127.0.0.1") String clientIp) {
        
        try {
            log.info("模拟连接建立: userId={}, clientIp={}", userId, clientIp);
            resourceProtectionService.recordConnectionEstablished(userId, clientIp);
            return Result.success("连接建立记录成功");
            
        } catch (Exception e) {
            log.error("模拟连接建立失败: userId={}, clientIp={}", userId, clientIp, e);
            return Result.error("模拟连接建立失败: " + e.getMessage());
        }
    }

    /**
     * 模拟连接断开（用于测试）
     *
     * @param userId 用户ID
     * @param clientIp 客户端IP
     * @return 操作结果
     */
    @PostMapping("/simulate-disconnection")
    public Result<String> simulateConnectionClosed(
            @RequestParam Long userId,
            @RequestParam(required = false, defaultValue = "127.0.0.1") String clientIp) {
        
        try {
            log.info("模拟连接断开: userId={}, clientIp={}", userId, clientIp);
            resourceProtectionService.recordConnectionClosed(userId, clientIp);
            return Result.success("连接断开记录成功");
            
        } catch (Exception e) {
            log.error("模拟连接断开失败: userId={}, clientIp={}", userId, clientIp, e);
            return Result.error("模拟连接断开失败: " + e.getMessage());
        }
    }
}